<!--
 * @Author: ssj
 * @Date: 2021-06-26 17:51:15
 * @LastEditors: wiz
 * @LastEditTime: 2023-11-21 17:00:41
 * @Description: 文件管理
-->
<template>
  <div class="file-upload" :style="showAnimation">
    <div class="back"></div>
    <div
      class="front"
      @dragenter="prevDrag"
      @dragover="prevDrag"
      @dragleave="dragLeave"
      @drop="dropFile"
    >
      <div class="drop-box" v-show="isDragShow">
        <div class="drop-box-cover">
          <Icon type="ios-cloud-outline"></Icon>
          <span>
            <!-- 拖入文件 -->
            {{ $srv.getI18nByPath('oFileManager.draginfile') }}
          </span>
        </div>
      </div>
      <div class="box" @click="activedFileIndex = null">
        <div class="close-btn" @click="close">
          <Icon type="ios-close" />
        </div>
        <div class="upload-btn">
          <input type="file" @change="selectFile" multiple />
          <Button size="small">
            <!-- 上传 -->
            {{ $srv.getI18nByPath('oFileManager.upload') }}
          </Button>
        </div>
        <div class="confirm-btn" v-if="tabName === 'tab_1'">
          <Button size="small" type="primary" @click="finish">
            <!-- 确认选择 -->
            {{ $srv.getI18nByPath('oFileManager.confirmselection') }}
          </Button>
        </div>
        <div class="start-btn" v-if="tabName === 'tab_3'">
          <Button
            type="primary"
            size="small"
            @click="upload"
            :disabled="uploadFileList.length === 0"
          >
            <!-- 开始传输 -->
            {{ $srv.getI18nByPath('oFileManager.starttransfer') }}
          </Button>
        </div>
        <div class="detail-panel" @click="$event.stopPropagation()">
          <div v-show="activedFileIndex !== null">
            <div class="file-detail-box">
              <div class="file-detail-title">
                <span>
                  <!-- 文件名 -->
                  {{ $srv.getI18nByPath('oFileManager.filename') }}
                  :</span
                >
              </div>
              <div class="file-detail-de">
                <i-input
                  v-model="activeFileInfo.title"
                  @on-change="onDetailChange"
                ></i-input>
              </div>
            </div>
            <div class="file-detail-box">
              <div class="file-detail-preview" @click="previewFile">
                <!-- 预览 -->
                {{ $srv.getI18nByPath('oFileManager.preview') }}
              </div>
            </div>
            <div class="file-detail-box">
              <div class="file-detail-download" @click="downloadFile">
                <!-- 下载文件 -->
                {{ $srv.getI18nByPath('oFileManager.downloadfile') }}
              </div>
            </div>
            <div class="file-detail-box">
              <div class="file-detail-title">
                <span>
                  <!-- 关联标签 -->
                  {{ $srv.getI18nByPath('oFileManager.associatedlabel') }}
                  :</span
                >
                <Button size="small" @click="selectTag">
                  <!-- 添加标签 -->
                  {{ $srv.getI18nByPath('oFileManager.addtag') }}
                </Button>
              </div>
              <div class="file-detail-de">
                <div
                  class="file-detail-tag"
                  v-for="(tag, iidx) of activeFileInfo.tags"
                  :key="iidx"
                >
                  {{ tag.text }}
                  <Icon type="ios-close" @click="removeTag(iidx)"></Icon>
                </div>
              </div>
            </div>
            <Button
              class="file-save-info"
              type="primary"
              v-show="isShowSaveFileInfo"
              @click="saveFileChanges"
            >
              <!-- 保存修改 -->
              {{ $srv.getI18nByPath('others.savechanges') }}
            </Button>
          </div>
        </div>
        <Tabs v-model="tabName" :animated="false" class="show-panel">
          <!-- <TabPane label="当前选择" name="tab_1" v-if="hasCurrent"> -->
          <TabPane
            :label="$srv.getI18nByPath('oFileManager.currentselection')"
            name="tab_1"
            v-if="hasCurrent"
          >
            <div class="manager-selected">
              <div
                class="file-box"
                v-for="(item, idx) of selectedFileList"
                :key="idx"
              >
                <div class="file-box-cover">
                  <div class="file-box-name">
                    {{ item.title + '.' + item.ext }}
                  </div>
                  <Icon
                    class="file-box-remove"
                    type="ios-close"
                    @click="removeSelectedFile(idx)"
                  ></Icon>
                  <div
                    class="file-box-preview"
                    @click="handleFileClick($event, idx, 'selected')"
                  >
                    <img :src="item.src" />
                  </div>
                  <span
                    class="file-box-seleced"
                    v-if="idx === activedFileIndex"
                  ></span>
                </div>
              </div>
            </div>
          </TabPane>
          <!-- <TabPane label="文件库" name="tab_2"> -->
          <TabPane
            :label="$srv.getI18nByPath('oFileManager.filelibrary')"
            name="tab_2"
          >
            <div class="manager-file">
              <div class="tag-list">
                <o-tree-grid
                  :config="tagTreeConfig"
                  @on-row-change="handleTagRowChange"
                ></o-tree-grid>
                <div class="v-line"></div>
                <div class="no-tag-filter" v-show="showTagFilter">
                  <Checkbox
                    v-model="noTagFilter"
                    @on-change="noTagFilterChange"
                  >
                    <!-- 过滤无标签文件 -->
                    {{
                      $srv.getI18nByPath('oFileManager.filterunlabeledfiles')
                    }}
                  </Checkbox>
                </div>
              </div>
              <div class="file-list">
                <div class="file-list-toolbar">
                  <Button size="small" @click="checkboxAll">
                    <!-- 全选 -->
                    {{ $srv.getI18nByPath('others.selectall') }}
                  </Button>
                  <Button size="small" @click="reverseCheckboxAll">
                    <!-- 取消选中 -->
                    {{ $srv.getI18nByPath('others.uncheck') }}
                  </Button>
                  <Button
                    :disabled="checkboxFileList.length === 0"
                    size="small"
                    @click="removeFile"
                  >
                    <!-- 删除 -->
                    {{ $srv.getI18nByPath('others.delete') }}
                  </Button>
                  <Button
                    v-if="mode !== MODE.RDONLY"
                    :disabled="checkboxFileList.length === 0"
                    size="small"
                    @click="addFileToSelected"
                  >
                    <!-- 添加到当前选择 -->
                    {{
                      $srv.getI18nByPath('oFileManager.addtocurrentselection')
                    }}
                  </Button>
                </div>
                <div class="file-list-cover y-scroll">
                  <div
                    class="file-box"
                    v-for="(item, idx) of filteredFileList"
                    :key="idx"
                  >
                    <div class="file-box-cover">
                      <div class="file-box-name">
                        {{ item.title + '.' + item.ext }}
                      </div>
                      <Checkbox
                        class="file-box-check"
                        v-model="item.checked"
                        @on-change="onCheckboxChange"
                      ></Checkbox>
                      <div
                        class="file-box-preview"
                        @click="handleFileClick($event, idx, 'filtered')"
                      >
                        <img :src="item.src" />
                      </div>
                      <span
                        class="file-box-seleced"
                        v-if="idx === activedFileIndex"
                      ></span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </TabPane>
          <!-- <TabPane label="传输列表" name="tab_3"> -->
          <TabPane
            :label="$srv.getI18nByPath('oFileManager.transmissionlist')"
            name="tab_3"
          >
            <div class="manager-upload">
              <div
                class="file-box upload-box"
                v-for="(item, idx) of uploadFileList"
                :key="idx"
              >
                <div class="file-box-cover">
                  <div class="file-box-name">
                    {{ item.title + '.' + item.ext }}
                  </div>
                  <Icon
                    class="file-box-remove"
                    type="ios-close"
                    @click="removeUploadFile(idx)"
                  ></Icon>
                  <div
                    class="file-box-preview"
                    @click="handleFileClick($event, idx, 'upload')"
                  >
                    <img :src="item.src" />
                  </div>
                  <span
                    class="file-box-seleced"
                    v-if="idx === activedFileIndex"
                  ></span>
                  <div class="file-box-extra">
                    <Checkbox
                      v-model="item.addSelected"
                      :disabled="mode === MODE.RDONLY"
                    >
                      <!-- 同步到当前选择 -->
                      {{
                        $srv.getI18nByPath(
                          'oFileManager.synctocurrentselection'
                        )
                      }}
                    </Checkbox>
                  </div>
                  <iCircle
                    v-show="
                      uploadProgress[item.sig] > 0 &&
                        uploadProgress[item.sig] < 100
                    "
                    :percent="uploadProgress[item.sig]"
                    :stroke-width="10"
                  ></iCircle>
                </div>
              </div>
            </div>
          </TabPane>
        </Tabs>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { Tsrv, ifs } from '@/services';
import { Component, Prop, Vue } from 'vue-property-decorator';
import { I_file, I_tag, I_tagTree } from './filetypes';
import treeConfig from './tagTree';

@Component
export default class oFileManager extends Vue {
  [x: string]: any;

  @Prop() config: any;

  @Prop({
    type: Number,
    default: 0
  })
  id: string;

  private MODE: { [key: string]: number } = {
    DEFAULT: 0,
    RDONLY: 1
  };

  private showAnimation: object = {};

  // 显示动画
  private checkboxFileList: any[] = [];

  // 选中文件
  private noTagFilter: boolean = false;

  // 过滤无标签文件
  private showTagFilter: boolean = true;

  // 显示过滤无标签
  private tabName: string = 'tab_1';

  // 标签
  private activedFileIndex = null;

  // 选中文件序号
  private activeFileInfo: I_file = {};

  // 选中文件信息
  private storedFileInfo: I_file = {};

  private activeArea: string = '';

  private isShowSaveFileInfo: boolean = false;

  private selectedFileList: I_file[] = [];

  // 当前选择的文件列表
  private uploadFileList: I_file[] = [];

  // 上传文件数据
  private uploadIndex: number = 1;

  // 上传文件序号
  private uploadProgress: { [key: number]: number } = {};

  // 上传进度
  private uploading: boolean = false;

  // 上传中
  private limit: number = 1;

  // 最大限制
  private isDragShow: boolean = false;

  // 拖拽面板
  private tagTreeConfig: any = treeConfig;

  // 树形配置
  private cachedFileInfo = [];

  private filteredFileList: I_file[] = [];

  private currenRows: any[] = [];

  // 选中树形标签
  private hasCurrent: boolean = true;

  // 是否有当前选择
  private mode: number = this.MODE.DEFAULT;

  private onlyImg: boolean = false;

  // 是否仅显示图片
  private defaultTags: I_tag[] = []; // 默认标签

  mounted() {
    this.show();
    this.init();
  }

  /**
   * @Author: ssj
   * @description: 初始化
   */
  private init(): void {
    const upload: any[] = this.config.upload || [];
    const selectedList: any[] = this.config.selected || [];
    this.limit = this.config.limit || 1;
    if (this.config.action === 'upload') {
      this.tabName = 'tab_3';
    } else if (this.config.action === 'file') {
      this.tabName = 'tab_2';
    } else if (this.config.action === 'select') {
      this.tabName = 'tab_1';
    }
    this.hasCurrent = this.config.hasCurrent;
    this.onlyImg = this.config.onlyImg || false;
    this.mode = this.config.mode
      ? this.MODE[this.config.mode]
      : this.MODE.DEFAULT;
    this.initDefaultTags();
    this.initSelectedFile(selectedList);
    this.initUploadFile(upload);
    setTimeout(() => {
      this.autoUpload();
    }, 500);
  }

  /**
   * @Author: ssj
   * @description: 初始化默认标签
   */
  private initDefaultTags(): void {
    this.config.tags.length &&
      this.config.tags.forEach(async (el: number) => {
        const data: I_tag[] = await this.requestGetTags(el);
        this.defaultTags.push(...data);
      });
  }

  /**
   * @Author: ssj
   * @param {any} list 文件信息
   * @description: 初始化已有的文件信息
   */
  private initSelectedFile(list: any): void {
    this.selectedFileList = [];
    list.forEach(el => {
      this.selectedFileList.push({
        id: el.id,
        name: el.name,
        src: el.src ? el.src : null,
        title: Tsrv.utils.getFileName(el.name),
        ext: Tsrv.utils.getFileExt(el.name),
        type: Tsrv.utils.getFileType(el.name),
        tags: []
      });
    });
    this.loadPreviewImages(this.selectedFileList);
  }

  /**
   * @Author: ssj
   * @param {any} list 文件信息
   * @description: 初始化待上传的文件
   */
  private initUploadFile(list: any): void {
    this.uploadFileList = [];
    this.appendUploadFile(list);
  }

  /**
   * @Author: ssj
   * @description: 预览文件
   */
  private previewFile(): void {
    const url: string = Tsrv.utils.getFileSrc(this.activeFileInfo.id, false);
    const handler: Window = window.open(url);
    let time: number = 0;
    if (Tsrv.utils.getFileType(`.${this.activeFileInfo.ext}`) !== 'image') {
      time = 500;
    }
    handler.onload = () => {
      setTimeout(() => {
        const html: HTMLHtmlElement = handler.document.getElementsByTagName(
          'html'
        )[0];
        const head: HTMLHeadElement = document.createElement('head');
        const title: HTMLTitleElement = document.createElement('title');
        const icon: HTMLLinkElement = document.createElement('link');

        title.appendChild(document.createTextNode(this.activeFileInfo.title));
        head.appendChild(title);
        icon.setAttribute('rel', 'icon');
        icon.setAttribute('type', 'image/png');
        icon.setAttribute('size', '32x32');
        icon.setAttribute('href', '/img/icons/favicon-32x32.png');
        head.appendChild(icon);
        html.insertBefore(head, html.childNodes[0]);
      }, time);
    };
  }

  /**
   * @Author: ssj
   * @description: 下载文件
   */
  private downloadFile(): void {
    Tsrv.utils.downloadFile(
      Tsrv.utils.getFileSrc(this.activeFileInfo.id, false),
      this.activeFileInfo.title
    );
  }

  /**
   * @Author: ssj
   * @description: 自动上传
   */
  private autoUpload(): void {
    if (this.config.action === 'upload' && this.config.tags.length) {
      this.upload();
    }
  }

  /**
   * @Author: ssj
   * @param {any} e
   * @description: 拖拽放下
   */
  private prevDrag(e: any): void {
    e.stopPropagation();
    e.preventDefault();
    this.isDragShow = true;
  }

  /**
   * @Author: ssj
   * * @param {any} e
   * @description: 拖拽离开
   */
  private dragLeave(e: any): void {
    e.stopPropagation();
    e.preventDefault();
    this.isDragShow = false;
  }

  /**
   * @Author: ssj
   * @param {any} e
   * @description: 拖拽上传文件
   */
  private dropFile(e: any): void {
    e.stopPropagation();
    e.preventDefault();
    this.isDragShow = false;
    this.tabName = 'tab_3';
    const files: any = e.dataTransfer.files;
    this.appendUploadFile(files);
  }

  /**
   * @Author: ssj
   * @description: 保存文件信息
   */
  private saveFileChanges(): void {
    const msg = this.$Message.loading({
      // content: `正在修改`,
      content: Tsrv.getI18nByPath('oFileManager.modifying') as string,
      duration: 0
    });
    const params = {
      fileId: this.activeFileInfo.id,
      fileName: `${this.activeFileInfo.title}.${this.activeFileInfo.ext}`,
      tagIds: this.activeFileInfo.tags.map(el => el.id)
    };
    Tsrv.httpReqV1
      .fun('_sys_p_updatefileinfo', params)
      .then(res => {
        // @ts-ignore
        msg();
        res = res.data;
        if (res.success) {
          this.storedFileInfo = Tsrv.utils.clone(this.activeFileInfo, true);
          const index = Tsrv.utils.findIndexOf(
            this.cachedFileInfo,
            el => el.id === this.storedFileInfo.id
          );
          if (index !== null) {
            this.cachedFileInfo.splice(
              index,
              1,
              Tsrv.utils.clone(this.storedFileInfo, true)
            );
          }
          // this.$Message.success("修改成功");
          this.$Message.success(
            Tsrv.getI18nByPath('oFileManager.successfullymodified')
          );
          this.onDetailChange();
        } else {
          // this.$msg("修改失败");
          this.$msg(Tsrv.getI18nByPath('oFileManager.failedmodified'));
        }
      })
      .catch(() => {
        // @ts-ignore
        msg();
      });
  }

  /**
   * @Author: ssj
   * @param {any} list 文件信息
   * @description: 上传文件
   */
  private appendUploadFile(list: any): void {
    list.forEach((el: any, idx: number) => {
      this.uploadFileList.push({
        name: el.name,
        src: null,
        title: Tsrv.utils.getFileName(el.name),
        ext: Tsrv.utils.getFileExt(el.name),
        type: Tsrv.utils.getFileType(el.name),
        file: el,
        addSelected: this.mode !== this.MODE.RDONLY,
        sig: this.uploadIndex,
        tags: this.defaultTags
      });
      this.$set(this.uploadProgress, this.uploadIndex, 0);
      this.uploadIndex++;
    });
    this.loadPreviewImages(this.uploadFileList);
  }

  /**
   * @Author: ssj
   * @description: 全选
   */
  private checkboxAll(): void {
    this.filteredFileList.forEach((el: I_file) => {
      el.checked = true;
    });
    this.onCheckboxChange();
  }

  /**
   * @Author: ssj
   * @description: 反选
   */
  private reverseCheckboxAll(): void {
    this.filteredFileList.forEach((el: I_file) => {
      el.checked = false;
    });
    this.onCheckboxChange();
  }

  /**
   * @Author: ssj
   * @param {I_file[]} list 文件信息
   * @description: 生成文件图标的路径
   */
  private loadPreviewImages(list: I_file[]): void {
    list.forEach((el: I_file) => {
      if (el.type === 'image') {
        if (el.id && !el.src) {
          el.src = Tsrv.utils.getFileSrc(el.id);
        } else if (!el.id && !el.src && el.file) {
          this.loadImageFromFile(el.file).then((res: string) => {
            el.src = res;
          });
        }
      } else {
        el.src = this.getFileIcon(el.type);
      }
    });
  }

  /**
   * @Author: ssj
   * @param {string} type 文件类型
   * @return {string} 图标路径
   * @description: 获取文件图标
   */
  private getFileIcon(type: string): string {
    return `${this.$config.publicURL}img/icons/file/${type}.png`;
  }

  /**
   * @Author: ssj
   * @description: 删除文件
   */
  private removeFile(): void {
    if (this.checkboxFileList.length > 0) {
      this.$Modal.confirm({
        // title: "删除文件!",
        // content: "是否删除当前选中" + this.checkboxFileList.length + "个文件",
        // okText: "确定",
        // cancelText: "取消",
        title: `${Tsrv.getI18nByPath('oFileManager.deletefiles')}!`,
        content:
          (Tsrv.getI18nByPath('oFileManager.whetherdelete') as string) +
          this.checkboxFileList.length +
          Tsrv.getI18nByPath('oFileManager.files'),
        okText: Tsrv.getI18nByPath('others.ok') as string,
        cancelText: Tsrv.getI18nByPath('others.cancel') as string,
        onOk: () => {
          this.doRemoveFiles();
        }
      });
    }
  }

  /**
   * @Author: ssj
   * @description: 把选中文件添加到当前选择
   */
  private addFileToSelected(): void {
    if (this.checkboxFileList.length > 0) {
      this.checkboxFileList.forEach(el => {
        this.selectedFileList.push({
          id: el.id,
          name: el.name,
          src: el.src,
          title: el.title,
          ext: el.ext,
          type: el.type,
          tags: Tsrv.utils.clone(el.tags, true)
        });
      });
    }
    this.reverseCheckboxAll();
  }

  /**
   * @Author: ssj
   * @description: 删除文件
   */
  private async doRemoveFiles(): Promise<void> {
    const { data } = await Tsrv.httpReqV1.delFile({
      fileIds: this.checkboxFileList.map(el => el.id)
    });
    if (data.success) {
      this.requestGetFileList(this.currenRows);
    }
    this.$msg(data.msg);
  }

  /**
   * @Author: ssj
   * @param {boolean} value 过滤标签
   * @description: 切换过滤标签
   */
  private noTagFilterChange(value: boolean): void {
    if (value) {
      this.requestGetFileList([
        {
          id: null
        }
      ]);
    } else {
      this.requestGetFileList(this.currenRows);
    }
  }

  /**
   * @Author: ssj
   * @param {any[]} rows 标签
   * @description: 点击树形切换标签
   */
  private handleTagRowChange(rows: any[]): void {
    this.currenRows = rows;
    if (rows[0]?.id) {
      this.noTagFilter = false;
      this.showTagFilter = false;
    } else {
      this.showTagFilter = true;
    }
    if (rows.length) {
      this.requestGetFileList(rows);
    } else {
      this.filteredFileList = [];
    }
  }

  private loadImageFromFile(file: any) {
    return new Promise(resolve => {
      if (window.FileReader) {
        const fr = new FileReader();
        fr.onloadend = e => {
          resolve(e.target.result);
        };
        fr.readAsDataURL(file);
      }
    });
  }

  /**
   * @Author: ssj
   * @description: 详情改变
   */
  private onDetailChange(): void {
    if (this.activeArea === 'selected' || this.activeArea === 'filtered') {
      let flag: boolean = false;
      if (this.storedFileInfo.title !== this.activeFileInfo.title) {
        flag = true;
      }
      if (this.storedFileInfo.tags.length === this.activeFileInfo.tags.length) {
        for (let i = 0; i < this.activeFileInfo.tags.length; i++) {
          if (
            !Tsrv.utils.find(
              this.storedFileInfo.tags,
              el => el.id === this.activeFileInfo.tags[i].id
            )
          ) {
            flag = true;
            break;
          }
        }
      } else {
        flag = true;
      }
      this.isShowSaveFileInfo = flag;
    }
  }

  /**
   * @Author: ssj
   * @description: 清除选中文件信息
   */
  private clearActiveFileInfo(): void {
    this.activeFileInfo.tags = [];
    this.activeFileInfo.title = '';
  }

  private handleFileClick(ev: MouseEvent, index: number, area: string): void {
    ev.stopPropagation();
    ev.preventDefault();
    this.activedFileIndex = index;
    this.activeArea = area;
    if (area === 'selected' || area === 'filtered') {
      const fileId =
        area === 'selected'
          ? this.selectedFileList[index].id
          : this.filteredFileList[index].id;
      this.clearActiveFileInfo();
      const cache = Tsrv.utils.find(
        this.cachedFileInfo,
        el => el.id === fileId
      );
      if (cache) {
        this.activeFileInfo = Tsrv.utils.clone(cache, true);
        this.storedFileInfo = Tsrv.utils.clone(cache, true);
      } else {
        const ids = [];
        const list =
          area === 'selected' ? this.selectedFileList : this.filteredFileList;
        list.forEach(el => {
          if (
            !Tsrv.utils.find(this.cachedFileInfo, item => item.id === el.id)
          ) {
            ids.push(el.id);
          }
        });
        const params = {
          fileIds: ids
        };

        params['getName'] = '_sys_p_getfileinfo';
        Tsrv.standardPostReq<ifs.I_queryRes<any>, any>(params, Tsrv.url.get)
          .then(([res, err]) => {
            this.$msg(err ?? res.msg);
            if (res.success) {
              const json = res.data.rows[0].FRtlJson;
              try {
                const data = Tsrv.utils.toStringJSON(json);
                data.forEach(item => {
                  const info: I_file = {
                    name: item.fileName,
                    title: Tsrv.utils.getFileName(item.fileName),
                    ext: Tsrv.utils.getFileExt(item.fileName),
                    type: Tsrv.utils.getFileType(item.fileName),
                    id: item.fileId,
                    src: null,
                    tags: [],
                    checked: false
                  };
                  if (item.fileTagPaths.length > 0) {
                    const treeData: I_tagTree[] = Tsrv.utils.toArrayTree(
                      item.fileTagPaths,
                      {
                        key: 'tagId',
                        parentKey: 'pid'
                      }
                    );

                    if (treeData.length > 0) {
                      info.tags = this.treeToTag(treeData);
                    }
                  }
                  this.cachedFileInfo.push(info);
                  if (item.fileId === fileId) {
                    this.activeFileInfo = Tsrv.utils.clone(info, true);
                    this.storedFileInfo = Tsrv.utils.clone(info, true);
                  }
                });
              } catch {
                console.error(
                  `json ${Tsrv.getI18nByPath('oFileManager.wrongformat')}`
                );
              }
            } else {
              this.$msg(Tsrv.getI18nByPath('oFileManager.failedtoload'));
            }
          })
          .catch(e => {
            console.error(e);
          });
      }
    } else if (area === 'upload') {
      this.activeFileInfo = this.uploadFileList[index];
    }
  }

  /**
   * @Author: ssj
   * @param {number} index 序号
   * @description: 移除标签
   */
  private removeTag(index: number): void {
    this.activeFileInfo.tags.splice(index, 1);
    this.onDetailChange();
  }

  /**
   * @Author: ssj
   * @description: 选择标签
   */
  private selectTag(): void {
    Tsrv.utils
      .createModal('oMagicBox', {
        source: { funid: null, field: '_sys_Tags', limit: 99 },
        config: {
          isFunLayout: true
        }
      })
      .then(data => {
        if (data && data.length > 0) {
          if (
            !Tsrv.utils.find(
              this.activeFileInfo.tags,
              el => el.id === data[0].id
            )
          ) {
            const msg = this.$Message.loading({
              // content: `正在添加`,
              content: Tsrv.getI18nByPath('oFileManager.adding') as string,
              duration: 0
            });
            data.forEach(el => {
              this.requestGetTags(el.id).then((datas: I_tag[]) => {
                this.activeFileInfo.tags.push(...datas);
                this.onDetailChange();
              });
            });

            // @ts-ignore
            msg();
          }
        }
      });
  }

  /**
   * @Author: ssj
   * @param {I_tagTree} tree 标签树
   * @return {I_tag} 标签数组
   * @description: 讲标签树转化为标签数组
   */
  private treeToTag(tree: I_tagTree[]): I_tag[] {
    const arr: I_tag[] = [];
    for (let s: number = 0; s < tree.length; s++) {
      const str = '';
      this.treeToTagLoop(tree[s], str, arr);
    }
    return arr;
  }

  /**
   * @Author: ssj
   * @param {I_tagTree} obj 父子对象
   * @param {string} str 标签名
   * @param {I_tag[]} arr 标签数组
   * @description: 合并父子标签
   */
  private treeToTagLoop(obj: I_tagTree, str: string, arr: I_tag[]): void {
    if (obj.children.length > 0) {
      for (let i: number = 0; i < obj.children.length; i++) {
        str += `${obj.tagName}/`;
        this.treeToTagLoop(obj.children[i], str, arr);
      }
    } else {
      str += obj.tagName;
      arr.push({
        id: obj.tagId,
        text: str
      });
    }
  }

  /**
   * @Author: ssj
   * @param {number} index 序号
   * @description: 删除上传中的文件
   */
  private removeUploadFile(index: number): void {
    delete this.uploadProgress[this.uploadFileList[index].sig];
    this.uploadFileList.splice(index, 1);
  }

  /**
   * @Author: ssj
   * @param {number} index 序号
   * @description: 删除当前选择文件
   */
  private removeSelectedFile(index: number) {
    this.selectedFileList.splice(index, 1);
  }

  /**
   * @Author: ssj
   * @param {any} e
   * @description: 选择文件准备上传
   */
  private selectFile(e: any): void {
    this.tabName = 'tab_3';
    const files: any = e.target.files;
    this.appendUploadFile(files);
  }

  /**
   * @Author: ssj
   * @description: 打开文件管理
   */
  public show(): void {
    this.showAnimation = {
      display: 'block',
      // 'z-index': 102 + this.id
      'z-index': 202 + this.id
    };
    setTimeout(() => {
      this.showAnimation = {
        display: 'block',
        opacity: 1,
        // 'z-index': 102 + this.id
        'z-index': 202 + this.id
      };
    }, 10);
  }

  /**
   * @Author: ssj
   * @description: 关闭文件管理
   */
  public close(): void {
    if (!this.uploading) {
      this.showAnimation = {
        display: 'block',
        opacity: 0,
        // 'z-index': 102 + this.id
        'z-index': 202 + this.id
      };
      setTimeout(() => {
        this.showAnimation = {
          display: 'none',
          // 'z-index': 102 + this.id
          'z-index': 202 + this.id
        };
        this.$bus.$emit(`modal_${this.id}`, null);
      }, 200);
    }
  }

  /**
   * @Author: ssj
   * @description: 传输上传文件
   */
  private upload(): void {
    if (this.uploadFileList.length > 0 && !this.uploading) {
      const files = []; // 文件列表
      const params = []; // 参数列表
      const processList = []; // 过程函数
      this.uploadFileList.forEach((el, idx) => {
        const param = { tags: [] };
        const file = el.file;
        const blob = file.slice(0, file.size, file.type);
        const newName = `${el.title}.${el.ext}`;
        const newFile = new File([blob], newName, {
          type: file.type
        });
        files.push(newFile);

        if (el.tags.length > 0) {
          el.tags.forEach(tag => {
            param.tags.push({
              fileName: newName,
              tagId: tag.id
            });
          });
        } else {
          param.tags.push({
            fileName: newName,
            tagId: null
          });
        }

        // 增加参数，过程
        params.push(param);
        processList.push(progress => {
          this.uploadProgress[el.sig] =
            (progress.loaded / progress.total) * 100;
        });
      });

      this.uploading = true;
      const msg = this.$Message.loading({
        // content: `正在上传`,
        content: `${Tsrv.getI18nByPath('oFileManager.uploading')}···`,
        duration: 0
      });
      // Tsrv.httpReqV1
      //   .uploadFile(files, params, processList)
      //   .then(res => {
      //     // @ts-ignore
      //     msg();
      //     this.uploading = false;
      //     const failedList = [];
      //     const totalCount = res.length;
      //     let failedCount = 0;
      //     res.forEach((item, idx) => {
      //       const data = item.data;
      //       if (data.success) {
      //         const fileName = data.files[0].fileName;
      //         const fileId = data.files[0].fileId;
      //         if (this.uploadFileList[idx].addSelected) {
      //           this.selectedFileList.push({
      //             id: fileId,
      //             name: fileName,
      //             src: null,
      //             title: Tsrv.utils.getFileName(fileName),
      //             ext: Tsrv.utils.getFileExt(fileName),
      //             type: Tsrv.utils.getFileType(fileName)
      //           });
      //         }
      //         delete this.uploadProgress[this.uploadFileList[idx].sig];
      //       } else {
      //         failedCount++;
      //         failedList.push(this.uploadFileList[idx]);
      //         this.uploadProgress[this.uploadFileList[idx].sig] = 100;
      //       }
      //     });
      //     this.uploadFileList = failedList;
      //     this.loadPreviewImages(this.selectedFileList);
      //     // this.$Message.success(
      //     //   "上传完成，成功" +
      //     //     (totalCount - failedCount) +
      //     //     "个，失败" +
      //     //     failedCount +
      //     //     "个"
      //     // );
      //     this.$Message.success(
      //       `${(Tsrv.getI18nByPath(
      //         'oFileManager.uploadcompletedsuccessful'
      //       ) as string) +
      //         (totalCount - failedCount)} ${Tsrv.getI18nByPath(
      //         'oFileManager.failed'
      //       )} ${failedCount}`
      //     );
      //     this.tabName = 'tab_1';
      //     this.requestGetFileList(this.currenRows);
      //   })
      //   .catch(e => {
      //     this.uploading = false;
      //   });
    }
  }

  /**
   * @Author: ssj
   * @description: 选中文件
   */
  private onCheckboxChange(): void {
    this.checkboxFileList =
      this.filteredFileList.filter((el: I_file) => el.checked === true) || [];
  }

  /**
   * @Author: ssj
   * @description: 确认选择
   */
  private finish(): void {
    if (this.selectedFileList.length > this.limit) {
      // this.$Message.info("最多选择" + this.limit + "个文件");
      this.$Message.info(
        (Tsrv.getI18nByPath('oFileManager.mostchoices') as string) +
          this.limit +
          Tsrv.getI18nByPath('oFileManager.files')
      );
    } else {
      const result = [];
      this.selectedFileList.forEach(el => {
        result.push({
          id: el.id,
          name: `${el.title}.${el.ext}`
        });
      });
      this.$bus.$emit(`modal_${this.id}`, result);
      this.close();
    }
  }

  /**
   * @Author: ssj
   * @param {number} tagID 标签id
   * @return {I_tag[]} 标签数组
   * @description: 获取标签数据
   */
  private requestGetTags(tagID: number): Promise<I_tag[]> {
    return new Promise((resolve, reject) => {
      const params = {
        tagId: tagID
      };

      params['spName'] = '_sys_p_getparenttag';
      Tsrv.standardPostReq<ifs.I_setDataRes, any>(params, Tsrv.url.fun)
        .then(([res, err]) => {
          if (res.success) {
            const data = res.data.rows;
            const treeData: I_tagTree[] = Tsrv.utils.toArrayTree(data, {
              key: 'tagId',
              parentKey: 'pid'
            });
            if (treeData.length > 0) {
              resolve(this.treeToTag(treeData));
            }
            resolve([]);
          } else {
            // this.$msg("添加失败");
            this.$msg(Tsrv.getI18nByPath('oFileManager.addfailed'));
            resolve([]);
          }
        })
        .catch(e => {
          console.error(e);
        });
    });
  }

  /**
   * @Author: ssj
   * @param {any[]} rows 标签
   * @description: 获取文件信息
   */
  private async requestGetFileList(rows: any[]): Promise<void> {
    // const onlyImg: string = this.onlyImg ? '1' : 'b.FTypeID';
    // const condition = rows.map(el =>
    //   el.id ? `a.FTagID = ${el.id}` : 'a.FTagID is null'
    // );
    // const { data } = await Tsrv.httpReqV1.query({
    //   fields:
    //     'b.id, b.FFileSize as size, b.FName as name, b.FCreateTime as create_time',
    //   sqlBody: `from _sys_File_Tags a join _sys_Files b on a.FFileID = b.id where b.FTypeID = ${onlyImg} and ${condition.join(
    //     ' or '
    //   )}`
    // });
    // if (data.success) {
    //   this.filteredFileList = [];
    //   data.rows.forEach(el => {
    //     if (
    //       !Tsrv.utils.find(
    //         this.filteredFileList,
    //         (item: I_file) => item.id === el.id
    //       )
    //     ) {
    //       this.filteredFileList.push({
    //         id: el.id,
    //         name: el.name,
    //         src: null,
    //         title: Tsrv.utils.getFileName(el.name),
    //         ext: Tsrv.utils.getFileExt(el.name),
    //         type: Tsrv.utils.getFileType(el.name),
    //         tags: [],
    //         checked: false
    //       });
    //     }
    //   });
    //   if (data.rows.length) {
    //     this.loadPreviewImages(this.filteredFileList);
    //   }
    // } else {
    //   this.$msg(data.msg);
    // }
    this.$msg(Tsrv.getI18nByValue('待修改'));
  }
}
</script>
<style lang="scss" scoped>
.manager-file {
  display: flex;
  width: 100%;
  height: 100%;
  .tag-list {
    width: 200px;
    height: 100%;
    flex-shrink: 0;
    position: relative;
    .wy-grid {
      height: calc(100% - 36px);
    }
    .v-line {
      position: absolute;
      height: 100%;
      right: 0;
      top: 0;
      width: 1px;
      z-index: 10;
      background-color: #e3e3e3;
    }
    .no-tag-filter {
      height: 36px;
      line-height: 36px;
      padding: 0 20px;
    }
  }
  .file-list {
    flex: 1;
    .file-list-toolbar {
      height: 43px;
      border-bottom: 1px solid #f7f7f7;
      display: flex;
      align-items: center;
      padding: 0 20px;
      .ivu-btn {
        margin-right: 12px;
      }
    }
    .file-list-cover {
      height: calc(100% - 43px);
      overflow-x: hidden;
    }
  }
}
.detail-panel {
  position: absolute;
  right: 0;
  top: 46px;
  height: calc(100% - 46px);
  overflow-x: hidden;
  overflow-y: auto;
  z-index: 1;
  width: 300px;
  background-color: #fff;
  border-left: 1px solid #ddd;
  .file-save-info {
    position: absolute;
    width: calc(100% - 40px);
    left: 20px;
    bottom: 20px;
    z-index: 1;
  }
  .file-detail-box {
    padding: 10px 15px 0;
    .file-detail-title {
      line-height: 28px;
      .ivu-btn {
        float: right;
      }
    }
    .file-detail-preview {
      height: 32px;
      line-height: 32px;
      text-align: center;
      border: 1px solid;
      border-color: var(--default-hover-font-color-light);
      color: var(--default-hover-font-color-light);
      cursor: pointer;
      border-radius: 2px;
      transition: ease-in-out 0.1s;
      &:hover {
        border-color: var(--default-hover-font-color);
        color: var(--default-hover-font-color);
      }
    }
    .file-detail-download {
      height: 34px;
      line-height: 34px;
      text-align: center;
      background-color: var(--default-hover-font-color-light);
      color: #fff;
      cursor: pointer;
      border-radius: 2px;
      transition: ease-in-out 0.1s;
      &:hover {
        background-color: var(--default-hover-font-color);
      }
    }
    .file-detail-tag {
      display: inline-block;
      background-color: var(--default-hover-font-color-light);
      color: #fff;
      border-radius: 4px;
      padding: 4px 24px 4px 8px;
      margin-right: 5px;
      margin-top: 5px;
      position: relative;
      .ivu-icon {
        position: absolute;
        right: 4px;
        top: 4px;
        font-size: 18px;
        color: #fff;
        cursor: pointer;
      }
    }
  }
}

.ivu-tabs ::v-deep {
  height: 100%;
  width: 100%;
  .ivu-tabs-bar {
    margin: 0;
    height: 46px;
    padding: 0 20px;
  }
  .ivu-tabs-content {
    height: calc(100% - 46px);
  }
  .ivu-tabs-tabpane {
    height: 100%;
  }
  .ivu-tabs-tab {
    padding: 14px 16px;
  }
}
.show-panel ::v-deep {
  .ivu-tabs-content {
    width: calc(100% - 300px);
  }
}
.confirm-btn,
.start-btn {
  right: 120px;
  position: absolute;
  z-index: 1;
  top: 10px;
}
.upload-btn {
  right: 55px;
  position: absolute;
  z-index: 1;
  overflow: hidden;
  top: 10px;
  .ivu-btn {
    float: left;
    position: relative;
    overflow: hidden;
  }
  input {
    width: 100%;
    position: absolute;
    opacity: 0;
    z-index: 1;
  }
}
.drop-box {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 22;
  background-color: rgba(255, 255, 255, 0.98);
  pointer-events: none;
  .drop-box-cover {
    display: flex;
    width: calc(100% - 80px);
    height: calc(100% - 80px);
    justify-content: center;
    align-items: center;
    flex-direction: column;
    margin: 40px;
    border: 1px dashed #bbb;
    .ivu-icon {
      font-size: 129px;
      color: #ddd;
      margin-top: -20px;
    }
    span {
      font-size: 36px;
      color: #ddd;
      margin-top: -10px;
    }
  }
}
.file-box {
  display: flex;
  float: left;
  width: 150px;
  margin: 15px 0 15px 20px;
  background-color: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  border-radius: 5px;
  flex-direction: column;
  height: 192px;
  &.upload-box {
    height: 222px;
  }
  .file-box-remove {
    position: absolute;
    right: 10px;
    top: 10px;
    font-size: 22px;
    font-weight: bold;
    cursor: pointer;
    color: #bbb;
  }
  .file-box-check {
    position: absolute;
    right: 0;
    top: 12px;
  }
  .file-box-cover {
    width: 100%;
    height: 100%;
    overflow: hidden;
    border-radius: 5px;
    position: relative;
  }
  .file-box-extra {
    width: 100%;
    height: 30px;
    line-height: 30px;
    border-top: 1px solid #f1f1f1;
    padding: 0 10px;
  }
  .file-box-name {
    line-height: 40px;
    padding: 0 40px 0 10px;
    text-overflow: ellipsis;
    overflow: hidden;
    height: 40px;
  }
  .ivu-chart-circle ::v-deep {
    position: absolute;
    width: 100% !important;
    height: 100% !important;
    display: block;
    padding: 80px 40px;
    left: 0;
    top: 0;
    background-color: rgba(0, 0, 0, 0.4);
    .ivu-icon {
      font-weight: bold;
      font-size: 90px;
      margin-top: 40px;
    }
  }
  .file-box-seleced {
    display: block;
    height: 3px;
    width: 100%;
    background-color: var(--default-hover-font-color);
    position: absolute;
    bottom: 0;
  }
  .file-box-preview {
    width: 150px;
    height: 150px;
    border-top: 1px solid #f1f1f1;
    cursor: pointer;
    padding: 5px;
    img {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
  }
}
//框架
.file-upload {
  position: absolute;
  z-index: 1001;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  opacity: 0;
  display: none;
  transition: ease-in-out 0.2s;
  .back {
    background-color: rgba(0, 0, 0, 0.5);
    width: 100%;
    height: 100%;
  }
  .front {
    position: absolute;
    width: calc(100% - 30px);
    height: calc(100% - 30px);
    top: 15px;
    left: 15px;
    .box {
      width: 100%;
      height: 100%;
      background-color: #fff;
      display: flex;
      flex-direction: column;
      border-radius: var(--border-radius-model);
      overflow: hidden;
      position: relative;
      .close-btn {
        position: absolute;
        right: 20px;
        width: 28px;
        height: 28px;
        cursor: pointer;
        color: #666;
        z-index: 1;
        top: 9px;
        .ivu-icon {
          font-size: 28px;
          font-weight: bold;
        }
      }
    }
  }
}
</style>
